/*
 * IBM Corporation.
 * Copyright (c) 2014 All Rights Reserved.
 */

package com.ibm.iisp.dataie.service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.persistence.EntityManager;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.lang3.StringUtils;

import com.ibm.iisp.common.exception.I18nAppException;
import com.ibm.iisp.common.util.BeanFactory;
import com.ibm.iisp.common.util.FileStoreUtils;
import com.ibm.iisp.dataie.vo.DataExportRequest;

/**
 * 类作用：
 * 
 * @author Johnny@cn.ibm.com 使用说明：
 */
public class CsvDataExporter extends AbstractDataExporter {
	private String expHead;
	private Object[] row;
	private BufferedWriter csvFileBos;
	CSVPrinter printer;
	/**
	 * @param dao
	 */
	public CsvDataExporter(DataExportRequest dataExportReq, EntityManager dao) {
		super(dataExportReq, dao);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.iisp.dataie.service.AbstractDataExporter#init(com.ibm.iisp.dataie.model.DataExportRequest)
	 */
	@Override
	public String init() throws I18nAppException {
		expHead = DataIEUtils.genDataFileHeader(dataExportReq);
		String rfilePath = DATA_EXP_FILE_ROOT;
		BeanFactory beanFactory = BeanFactory.getInstance();
		FileStoreUtils fileStoreUtils = beanFactory.getBean(FileStoreUtils.class);
		String absFilePath = fileStoreUtils.getAbsFilePath(rfilePath);
		File expDataFile = new File(absFilePath);
		expDataFile.mkdirs();

		String dName = dataExportReq.getFileName();
		if (StringUtils.isNotEmpty(dName)) {
			// 如果没有扩展名，则加上
			if (dName.indexOf(".") < 0) {
				dName += ".csv";
			}
		} else {
			dName = dataExportReq.getTableName() + ".csv";
		}

		String encodeFileName = fileStoreUtils.encodeFileName(dName);
		rfilePath += "/" + encodeFileName;
		absFilePath = absFilePath + "/" + encodeFileName;
		expDataFile = new File(absFilePath);
		try {
			csvFileBos = new BufferedWriter(new FileWriter(expDataFile));
			// 加上BOM标识,以便Excel能正确识别UTF-8编码
			csvFileBos.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF }));

			// 写出文件头部
			csvFileBos.write(expHead);
			printer = new CSVPrinter(csvFileBos, CSVFormat.DEFAULT);
		} catch (IOException e) {
			log.error("Failed to write data file.", e);
			throw new I18nAppException("IISP_DATA_WRITE_FILE", new String[] { e.getMessage() },
				"Error to write file:" + e.getMessage(), e);
		}
		return rfilePath;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.iisp.dataie.service.AbstractDataExporter#getExportCols(com.ibm.iisp.dataie.model.DataExportRequest)
	 */
	@Override
	protected String getExportCols() {
		int indexOf = expHead.indexOf("\n") + 1;
		return expHead.substring(indexOf, expHead.indexOf("\r", indexOf));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.iisp.dataie.service.AbstractDataExporter#exportRow(java.sql.ResultSet, int)
	 */
	@Override
	protected void exportRow(ResultSet rs, int colCount) throws SQLException, I18nAppException {
		if (row == null) {
			row = new Object[colCount];
		}
		for (int i = 1; i <= colCount; i++) {
			Object val = rs.getObject(i);
			row[i - 1] = val == null ? "" : val;
		}
		try {
			printer.printRecord(row);
		} catch (IOException e) {
			log.error("Failed to write data file.", e);
			throw new I18nAppException("IISP_DATA_WRITE_FILE", new String[] { e.getMessage() },
				"Error to write file:" + e.getMessage(), e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.iisp.dataie.service.AbstractDataExporter#finish()
	 */
	@Override
	public void finish() {
		row = null;
		expHead = null;
		if (csvFileBos != null) {
			try {
				printer.flush();
				csvFileBos.close();
				printer.close();
			} catch (IOException e) {
				log.error("Failed to close data file.", e);
			}
		}

	}

}
